
package com.tools.cleanmaster.utils;

import android.content.Context;
import android.os.Environment;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 遍历sd卡的任务
 * 
 * @author wangyi
 */
public class TraversalSDPathTask {

    private class ScanTargetFolderDir {
        public String targetPath = null;

        public int maxScanLevel = 0;

        public boolean needScan = false;
    }

    private static final String ANDROID_DATA = "/Android/data";

    private static final int MAX_SCANLEVEL = 1 + 1;// 算法层级从1开始的

    private Set<String> mSubDirs = new HashSet<String>();// 多个sd卡可能出现重复的路径，故用set集合排重

    /**
     * 遍历sd卡返回找到的path
     * 
     * @param context
     * @return
     */
    public List<String> traversalSD(Context context) {
        scanEnumSD(context);
        return new ArrayList<String>(mSubDirs);
    }

    private void scanEnumSD(Context context) {
        List<ScanTargetFolderDir> scanTargetFolderDirs = buildTargetDatas(
                new StorageList(context).getMountedVolumePaths(), MAX_SCANLEVEL);
        // 添加一些指定需要扫描的路径(例如：Android/data)
//        appendMoreTargetPaths(scanTargetFolderDirs);

        if (null != scanTargetFolderDirs) {
            Collections.sort(scanTargetFolderDirs, new Comparator<ScanTargetFolderDir>() {
                @Override
                public int compare(ScanTargetFolderDir obj1, ScanTargetFolderDir obj2) {
                    return obj1.targetPath.compareTo(obj2.targetPath);
                }
            });

            for (int idx = 0; idx < scanTargetFolderDirs.size(); ++idx) {
                ScanTargetFolderDir target = scanTargetFolderDirs.get(idx);
                if (target.needScan) {
                    File sdRoot = new File(target.targetPath);
                    int length=sdRoot.getAbsolutePath().length();
                    if(target.targetPath.contains(ANDROID_DATA)){
                        length=Environment.getExternalStorageDirectory().getPath().length();
                    }
                    listFilePaths(sdRoot, 0, target.maxScanLevel, length);
                }
            }
        }
    }

    /**
     * 根据层级限制遍历sd卡
     *
     * @param file
     * @param depth
     * @param maxDepth
     * @param sublength 获取文件名的时候需要的字段(需要剔除/mnt/sdcard/0 这类东西)
     */
    public void listFilePaths(File file, int depth, int maxDepth, int sublength) {
        if (file.isFile()) {
        } else {
            int currentDeep = depth + 1;
            if (currentDeep < maxDepth) {
                File[] subFils = null;
                try {
                    subFils = file.listFiles();// 这里有可能会产生OOM
                } catch (Throwable e) {
                }
                if (subFils != null && subFils.length > 0) {
                    for (File subFile : subFils) {
                        if (subFile.isFile()) {
                        } else {
                            onFoundDir(subFile.getAbsolutePath().substring(sublength));
                            listFilePaths(subFile, currentDeep, maxDepth, sublength);
                        }
                    }
                }
            }
        }
    }

    private void onFoundDir(String dir) {
        mSubDirs.add(dir.toLowerCase());
    }

    private void appendMoreTargetPaths(List<ScanTargetFolderDir> scanTargetFolderDirs) {
        if (null == scanTargetFolderDirs || scanTargetFolderDirs.isEmpty()) {
            return;
        }

        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            return;
        }

        String sdCardPath = Environment.getExternalStorageDirectory().getPath();
        if (null == sdCardPath) {
            return;
        }

        String targetPath = sdCardPath + ANDROID_DATA;
        if (new File(targetPath).exists()) {
            ScanTargetFolderDir target = new ScanTargetFolderDir();
            target.targetPath = targetPath;
            target.maxScanLevel = MAX_SCANLEVEL;
            target.needScan = true;
            scanTargetFolderDirs.add(target);
        }
    }

    protected List<ScanTargetFolderDir> buildTargetDatas(List<String> exStoragePaths, int maxLevel) {
        if (null == exStoragePaths || exStoragePaths.isEmpty()) {
            return null;
        }
        ArrayList<ScanTargetFolderDir> rst = new ArrayList<ScanTargetFolderDir>();
        ScanTargetFolderDir target = null;
        for (String path : exStoragePaths) {
            target = new ScanTargetFolderDir();
            target.targetPath = path;
            target.maxScanLevel = maxLevel;
            target.needScan = true;
            rst.add(target);
        }
        return rst;
    }

}
